#ifndef _XX_YY_BMOCK_RAW_MEM
#define _XX_YY_BMOCK_RAW_MEM

#include <boost/lexical_cast.hpp>
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
#include "bmock_raw_mem_checker.hpp"
#include "bmock_message.hpp"

namespace bmock {
	struct raw_mem {
		raw_mem();
		template<typename T>
		raw_mem(const T &value_,size_t len=1,typename boost::disable_if<boost::is_pointer<T> >::type* dummy = 0){
			dummy=0;
			if(len==0)
			{
				ptr_=NULL;
				len_=0;
			}
			else
			{
				ptr_=(unsigned char *const)(&value_);
				len_=len*sizeof(typename boost::remove_all_extents<T>::type);
			}
		}

		template<typename T>
		raw_mem(const T *const ptr,size_t len=1)
			:ptr_((unsigned char *const)(ptr))
			,len_(len*sizeof(T))
		{}

		raw_mem(const void *const ptr,const size_t len);
		raw_mem &            operator = (const raw_mem &);
		size_t               get_length() const;
		const unsigned char *get_ptr() const;
		const unsigned char *begin() const;
		unsigned char       *begin();
		const unsigned char *end() const;
		std::string          get_value() const;
		std::string          get_str_value() const;
		bool                 is_empty() const;
		bool                 set_value(const std::string &name,const raw_mem_checker &chk,const std::string &v) const;
		void                 set_value(size_t v_len,const std::string &v) const;
		template<typename T>
		std::string get_T_value() const {
			if(is_empty()) return NULL_STR;
			return boost::lexical_cast<std::string>(*get_T_ptr<T>());
		}
		template<typename T>
		const T *get_T_ptr() const {
			return reinterpret_cast<const T *>(ptr_);
		}
		template<typename T>
		T *get_T_ptr() {
			return reinterpret_cast<T *>(ptr_);
		}
	protected:
		unsigned char *ptr_;
		size_t         len_;
	};
	struct in_out_rm_pair : public std::pair<raw_mem,raw_mem> {
		in_out_rm_pair(const void *ptr,const std::string &name,const raw_mem_checker &chk);
	};
	struct in_rm  {
		in_rm(const void *ptr,const std::string &name,const raw_mem_checker &chk);
		raw_mem rm_;
	};
}

#endif
